[bits 32]
section .text

%define TRUE 1
%define FALSE 0

%macro INTERRUPT_VECTOR 2
interrupt_%1_handler:
%ifn %2 ; 没有错误码那就压入魔数占位
    push 0x20231208
%endif
push %1 ; 压入中断向量
jmp handler_entry
%endmacro

extern _handler_table
handler_entry:
    push ds
    push es
    push fs
    push gs
    pusha

    mov al, 0x20
    out 0x20, al
    out 0xa0, al

    mov eax, [esp + 48]
    push eax ; 压入中断号 方便调试
    call [_handler_table + eax * 4]
global _interrupt_exit
_interrupt_exit:
    add esp, 4
    popa
    pop gs
    pop fs
    pop es
    pop ds
    add esp, 8
    iret

INTERRUPT_VECTOR 0x00, FALSE
INTERRUPT_VECTOR 0x01, FALSE
INTERRUPT_VECTOR 0x02, FALSE
INTERRUPT_VECTOR 0x03, FALSE
INTERRUPT_VECTOR 0x04, FALSE
INTERRUPT_VECTOR 0x05, FALSE
INTERRUPT_VECTOR 0x06, FALSE
INTERRUPT_VECTOR 0x07, FALSE
INTERRUPT_VECTOR 0x08, TRUE
INTERRUPT_VECTOR 0x09, FALSE
INTERRUPT_VECTOR 0x0a, TRUE
INTERRUPT_VECTOR 0x0b, TRUE
INTERRUPT_VECTOR 0x0c, TRUE
INTERRUPT_VECTOR 0x0d, TRUE
INTERRUPT_VECTOR 0x0e, TRUE
INTERRUPT_VECTOR 0x0f, FALSE
INTERRUPT_VECTOR 0x10, FALSE
INTERRUPT_VECTOR 0x11, TRUE
INTERRUPT_VECTOR 0x12, FALSE
INTERRUPT_VECTOR 0x13, FALSE
INTERRUPT_VECTOR 0x14, FALSE
INTERRUPT_VECTOR 0x15, FALSE
INTERRUPT_VECTOR 0x16, FALSE
INTERRUPT_VECTOR 0x17, FALSE
INTERRUPT_VECTOR 0x18, FALSE
INTERRUPT_VECTOR 0x19, FALSE
INTERRUPT_VECTOR 0x1a, FALSE
INTERRUPT_VECTOR 0x1b, FALSE
INTERRUPT_VECTOR 0x1c, FALSE
INTERRUPT_VECTOR 0x1d, FALSE
INTERRUPT_VECTOR 0x1e, FALSE
INTERRUPT_VECTOR 0x1f, FALSE
INTERRUPT_VECTOR 0x20, FALSE
INTERRUPT_VECTOR 0x21, FALSE
INTERRUPT_VECTOR 0x22, FALSE
INTERRUPT_VECTOR 0x23, FALSE
INTERRUPT_VECTOR 0x24, FALSE
INTERRUPT_VECTOR 0x25, FALSE
INTERRUPT_VECTOR 0x26, FALSE
INTERRUPT_VECTOR 0x27, FALSE
INTERRUPT_VECTOR 0x28, FALSE
INTERRUPT_VECTOR 0x29, FALSE
INTERRUPT_VECTOR 0x2a, FALSE
INTERRUPT_VECTOR 0x2b, FALSE
INTERRUPT_VECTOR 0x2c, FALSE
INTERRUPT_VECTOR 0x2d, FALSE
INTERRUPT_VECTOR 0x2e, FALSE
INTERRUPT_VECTOR 0x2f, FALSE

section .data
global _handler_entry_table
_handler_entry_table:
    dd interrupt_0x00_handler
    dd interrupt_0x01_handler
    dd interrupt_0x02_handler
    dd interrupt_0x03_handler
    dd interrupt_0x04_handler
    dd interrupt_0x05_handler
    dd interrupt_0x06_handler
    dd interrupt_0x07_handler
    dd interrupt_0x08_handler
    dd interrupt_0x09_handler
    dd interrupt_0x0a_handler
    dd interrupt_0x0b_handler
    dd interrupt_0x0c_handler
    dd interrupt_0x0d_handler
    dd interrupt_0x0e_handler
    dd interrupt_0x0f_handler
    dd interrupt_0x10_handler
    dd interrupt_0x11_handler
    dd interrupt_0x12_handler
    dd interrupt_0x13_handler
    dd interrupt_0x14_handler
    dd interrupt_0x15_handler
    dd interrupt_0x16_handler
    dd interrupt_0x17_handler
    dd interrupt_0x18_handler
    dd interrupt_0x19_handler
    dd interrupt_0x1a_handler
    dd interrupt_0x1b_handler
    dd interrupt_0x1c_handler
    dd interrupt_0x1d_handler
    dd interrupt_0x1e_handler
    dd interrupt_0x1f_handler
    dd interrupt_0x20_handler
    dd interrupt_0x21_handler
    dd interrupt_0x22_handler
    dd interrupt_0x23_handler
    dd interrupt_0x24_handler
    dd interrupt_0x25_handler
    dd interrupt_0x26_handler
    dd interrupt_0x27_handler
    dd interrupt_0x28_handler
    dd interrupt_0x29_handler
    dd interrupt_0x2a_handler
    dd interrupt_0x2b_handler
    dd interrupt_0x2c_handler
    dd interrupt_0x2d_handler
    dd interrupt_0x2e_handler
    dd interrupt_0x2f_handler

section .text
extern _syscall_table
; 系统调用的中断处理程序
global _syscall_handler
_syscall_handler:
    push 0x20231208 ; 保持栈格式
    push 0x80

    push ds
    push es
    push fs
    push gs
    pusha

    push 0x80

    push edx ; 压入参数
    push ecx
    push ebx
    call [_syscall_table + eax * 4]

    add esp, 12
    mov [esp + 8 * 4], eax ; 修改返回值 
    jmp _interrupt_exit